package luck.technology.booktext;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import static luck.technology.booktext.BookText.UNDEFINED_COLOR;
import static luck.technology.booktext.BookText.UNDEFINED;

@SuppressLint("ClickableViewAccessibility")
public class BookTextView extends View implements View.OnTouchListener{

	private Context mContext;
	
	private BookText mText = null, mTextSample = null;
	
	private int 
			mLeft = 0,
			mTop = 0,
			mRight = 0,
			mBottom = 0,
			mTextColor = UNDEFINED_COLOR;
	
	private float mTextSize = UNDEFINED;
	private Typeface mTypeface = null;
	private boolean mJustify = true; 
	
	private String mTag = null;
	
	private void init(Context context) {
		
		mContext = context;
		setOnTouchListener(this);
	}
	
	public BookTextView(Context context) {
		super(context);
		
		init(context);
	}
	
	public BookTextView (Context context, AttributeSet attrs) {
		super(context, attrs);
		
		init(context);
	}
	
	public BookTextView (Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		
		init(context);
	}
	
	private BookText getTextSample(){
		
		if (mTextSample == null) {
			mTextSample = new BookText();
			mTextSample.process(mContext);
		}
		return mTextSample;
	}
	
	public void setTypeface (Typeface typeface) {
		
		mTypeface = typeface;
		
		if(mText != null){
			mText.setTypeface(typeface);
			mText.process(mContext);
			requestLayout();
		}
	}
	
	public Typeface getTypeface () {
		
		if (mText != null) return mText.getTypeface();
		if (mTypeface != null) return mTypeface;
		return BookText.DEF_TYPEFACE;
	}
	
	public void setJustify (boolean justify) {
		
		mJustify = justify;
		
		if (mText != null){
			mText.setJustify(justify);
			mText.process(mContext);
			requestLayout();
		}
	}
	
	public boolean getJustify () {
		
		if (mText != null) mText.getJustify();
		return mJustify;
	}
	
	public int getLineCount(){
		
		if (mText == null) return 0;
		return mText.mLines.size();
	}
	
	public void setTextSize(float textSize) {

		mTextSize = textSize;
		
		if (mText != null) {
			mText.setTextSize(textSize);
			mText.process(mContext);
			requestLayout();
		}
	}
	
	public float getTextSize(){
		
		if (mText != null) return mText.getTextSize();
		if (mTextSize != UNDEFINED) return mTextSize;
		return getTextSample().getTextSize();
	}
	
	public void setText (BookText text) {

		mText = text;
		if (mTextColor != UNDEFINED_COLOR) mText.setTextColor(mTextColor);
		if (mTextSize != UNDEFINED) mText.setTextSize(mTextSize);
		if (mTypeface != null) mText.setTypeface(mTypeface);
		mText.setJustify(mJustify);
		mText.process(mContext);
		requestLayout();
	}
	
	public BookText getText() {
		
		return mText;
	}
	
	public void setTextColor (int color){
		
		mTextColor = color;
		
		if(mText != null){
			mText.setTextColor(color);
			mText.process(mContext);
			requestLayout();
		}
	}
	
	public int getTextColor() {
		
		if (mText != null) return mText.getTextColor();
		if (mTextColor != UNDEFINED_COLOR) return mTextColor;
		return getTextSample().getTextColor();
	}
	
	private String getTextTag(float x, float y) {
		
		if (mText == null) return null;
		return mText.getTag(x - mLeft, y - mTop);
	}
	
	public String getTextTag() {
		
		return mTag;
	}

	@Override
	public void setPadding (int left, int top, int right, int bottom) {
		super.setPadding(left, top, right, bottom);
		
		mLeft = left;
		mTop = top;
		mRight = right;
		mBottom = bottom;
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

	    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
	    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
	    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
	    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

	    int width;
	    int height;

	    if (widthMode == MeasureSpec.EXACTLY) {
	        width = widthSize;
	    } else if (widthMode == MeasureSpec.AT_MOST) {
	        width = widthSize;
	    } else {
	    	DisplayMetrics dm = getResources().getDisplayMetrics(); 
	        width = dm.widthPixels;
	    }
	    
	    int desiredHeight = mText.format(width - mLeft - mRight) + mTop + mBottom;
	    
	    if (heightMode == MeasureSpec.EXACTLY) {
	        height = heightSize;
	    } else if (heightMode == MeasureSpec.AT_MOST) {
	        height = Math.min(desiredHeight, heightSize);
	    } else {
	        height = desiredHeight;
	    }

	    setMeasuredDimension(width, height);
	}
	
	@Override
	protected void onDraw (Canvas canvas) {
		super.onDraw(canvas);
				
		if (mText != null) mText.draw(canvas, mLeft, mTop);		
	}
	
	public int getLineBounds (int line, Rect bounds){
		
		int result = 0;
		Rect rect = new Rect();
		
		if (mText != null){
			
			result = mText.getLineBounds(line, rect);
		}
		if (result > 0) {
			
			result += mTop;
			rect.top += mTop;
			rect.bottom += mTop;
			rect.left += mLeft;
			rect.right += mLeft;
		}
		if (bounds != null) bounds.set(rect);
		
		return result;
	}	
	
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			mTag = getTextTag(event.getX(), event.getY());
		}
		return false;
	}
}
